package com.bulls.dsp.service.impl;

import com.bulls.dsp.common.PageInfo;
import com.bulls.dsp.common.util.DateHelper;
import com.bulls.dsp.mapper.AderMapper;
import com.bulls.dsp.mapper.PaymentMapper;
import com.bulls.dsp.exception.DuplicateException;
import com.bulls.dsp.bean.enums.PaymentType;
import com.bulls.dsp.bean.mybatis.Ader;
import com.bulls.dsp.bean.mybatis.Payment;
import com.bulls.dsp.service.IAderService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

@Service
@Transactional
public class AderServiceImpl implements IAderService {

    @Resource
    private AderMapper aderMapper;

    @Resource
    private PaymentMapper paymentMapper;

    @Override
    @Transactional(readOnly = true)
    public PageInfo<?> findAllEnableByIfNotNull(String name, int page, int size) {

        name = StringUtils.isEmpty(name) ? name : "%" + name.trim() + "%";

        List<Ader> aders = aderMapper.getAders(name, page, size);

        this.fillExtraFields(aders);

        return PageInfo.builder()
                .totalElements(aderMapper.getAderCountBy(name))
                .number(page)
                .size(size)
                .content(aders)
                .build();
    }

    private void fillExtraFields(List<Ader> aders) {
        aders.forEach(ader -> {
            ader.setBalance(this.getBalance(ader.getId(), null));
            ader.setCostHistory(this.getCostHistory(ader.getId()));
            ader.setCostToday(this.getCostToday(ader.getId()));
        });
    }

    @Override
    public void insertOrUpdate(Ader ader) {
        this.checkNameDuplicate(ader);

        if (ader.getId() == null) {
            ader.setToken(this.generateToken());
            aderMapper.insert(ader);
        } else {
            aderMapper.update(ader);
        }

    }

    private String generateToken() {
        int start = new Random().nextInt(28);
        return UUID.randomUUID().toString().substring(start, start + 8);
    }

    private void checkNameDuplicate(Ader ader) {

        Ader old = aderMapper.getAderByName(ader.getName());
        if (!(old == null || Objects.equals(ader.getId(), old.getId()))) {
            throw new DuplicateException("广告主名称重复,请重试");
        }

    }

    @Override
    public void disableByIds(String ids) {
        String[] id = ids.replace("\"", "").split(",");
        for (String s : id) {
            Long val = Long.valueOf(s);
            aderMapper.disableAder(val);
        }
    }

    @Override
    @Transactional(readOnly = true)
    public Float getBalance(Long aderId, Date endDate) {
        final Float[] balance = {0.0f};
        List<Payment> payments =
                paymentMapper.getAllByAderId(aderId, null,
                        null, DateHelper.time2Str(endDate));

        payments.forEach(
                payment ->
                        balance[0] =
                                payment.getPaymentType() == PaymentType.EXPEND.getValue() ?
                                        (balance[0] - payment.getAmount()) :
                                        (balance[0] + payment.getAmount())
        );
        return balance[0];
    }

    private Float getCostHistory(Long aderId) {
        final Float[] cost = {0.0f};
        List<Payment> payments =
                paymentMapper.getAllByAderId(aderId,
                        String.valueOf(PaymentType.EXPEND.getValue()),
                        null, null);
        payments.forEach(payment -> cost[0] += payment.getAmount());
        return cost[0];
    }

    private Float getCostToday(Long aderId) {
        final Float[] total = {0.0f};
        List<Payment> payments =
                paymentMapper.getAllByAderId(aderId,
                        String.valueOf(PaymentType.EXPEND.getValue()),
                        DateHelper.getTodayStartTimeStr(), null);

        payments.forEach(payment -> total[0] += payment.getAmount());

        return total[0];
    }
}
